<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: Script builder</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
  $(document).ready(function() { init_search(); });
/* @license-end */
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr id="projectrow">
  <td id="projectlogo"><img alt="Logo" src="aslogo_small.png"/></td>
  <td id="projectalign">
   <div id="projectname">AngelScript
   </div>
  </td>
    <td>        <div id="MSearchBox" class="MSearchBoxInactive">
        <span class="left">
          <span id="MSearchSelect"                onmouseover="return searchBox.OnSearchSelectShow()"                onmouseout="return searchBox.OnSearchSelectHide()">&#160;</span>
          <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)" 
               onblur="searchBox.OnSearchFieldFocus(false)" 
               onkeyup="searchBox.OnSearchFieldChange(event)"/>
          </span><span class="right">
            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
          </span>
        </div>
</td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.6 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
      <div id="nav-sync" class="sync"></div>
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(document).ready(function(){initNavTree('doc_addon_build.html',''); initResizable(); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>

<div><div class="header">
  <div class="headertitle"><div class="title">Script builder </div></div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p><b>Path:</b> /sdk/add_on/scriptbuilder/</p>
<p>This class is a helper class for loading and building scripts, with a basic pre-processor that supports conditional compilation, include directives, pragma directives, and metadata declarations.</p>
<p>By default the script builder resolves include directives by loading the included file from the relative directory of the file it is included from. If you want to do this in another way, then you should implement the <a class="el" href="doc_addon_build.html#doc_addon_build_1_1">include callback</a> which will let you process the include directive in a custom way, e.g. to load the included file from memory, or to support multiple search paths. The include callback should call the AddSectionFromFile or AddSectionFromMemory to include the section in the current build.</p>
<p>If the application should to support pragma directives, it must register the <a class="el" href="doc_addon_build.html#doc_addon_build_1_2">pragma callback</a> to process the text provided for the pragma directive. Without the callback the script builder will give an error when encountering a pragma directive.</p>
<p>The script builder will also remove any lines that start with <code>#!</code> as comments. This is done to support shebang interpreter directives often used on Linux and UNIX based operative systems.</p>
<p>If you do not want process metadata then you can compile the add-on with the define AS_PROCESS_METADATA 0, which will exclude the code for processing this. This define can be made in the project settings or directly in the header.</p>
<h1><a class="anchor" id="doc_addon_build_1"></a>
Public C++ interface</h1>
<div class="fragment"><div class="line"><span class="keyword">class </span>CScriptBuilder</div>
<div class="line">{</div>
<div class="line"><span class="keyword">public</span>:</div>
<div class="line">  <span class="comment">// Start a new module</span></div>
<div class="line">  <span class="keywordtype">int</span> StartNewModule(<a class="code hl_class" href="classas_i_script_engine.html">asIScriptEngine</a> *engine, <span class="keyword">const</span> <span class="keywordtype">char</span> *moduleName);</div>
<div class="line"> </div>
<div class="line">  <span class="comment">// Load a script section from a file on disk</span></div>
<div class="line">  <span class="comment">// Returns  1 if the file was included</span></div>
<div class="line">  <span class="comment">//          0 if the file had already been included before</span></div>
<div class="line">  <span class="comment">//         &lt;0 on error</span></div>
<div class="line">  <span class="keywordtype">int</span> AddSectionFromFile(<span class="keyword">const</span> <span class="keywordtype">char</span> *filename);</div>
<div class="line"> </div>
<div class="line">  <span class="comment">// Load a script section from memory</span></div>
<div class="line">  <span class="comment">// Returns  1 if the section was included</span></div>
<div class="line">  <span class="comment">//          0 if a section with the same name had already been included before</span></div>
<div class="line">  <span class="comment">//         &lt;0 on error</span></div>
<div class="line">  <span class="keywordtype">int</span> AddSectionFromMemory(<span class="keyword">const</span> <span class="keywordtype">char</span> *sectionName,</div>
<div class="line">                           <span class="keyword">const</span> <span class="keywordtype">char</span> *scriptCode, </div>
<div class="line">                           <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> scriptLength = 0,</div>
<div class="line">                           <span class="keywordtype">int</span> lineOffset = 0);</div>
<div class="line"> </div>
<div class="line">  <span class="comment">// Build the added script sections</span></div>
<div class="line">  <span class="keywordtype">int</span> BuildModule();</div>
<div class="line"> </div>
<div class="line">  <span class="comment">// Returns the script engine</span></div>
<div class="line">  <a class="code hl_class" href="classas_i_script_engine.html">asIScriptEngine</a> *GetEngine();</div>
<div class="line"> </div>
<div class="line">  <span class="comment">// Returns the current module</span></div>
<div class="line">  <a class="code hl_class" href="classas_i_script_module.html">asIScriptModule</a> *GetModule();</div>
<div class="line"> </div>
<div class="line">  <span class="comment">// Register the callback for resolving include directive</span></div>
<div class="line">  <span class="keywordtype">void</span> SetIncludeCallback(INCLUDECALLBACK_t callback, <span class="keywordtype">void</span> *userParam);</div>
<div class="line"> </div>
<div class="line">  <span class="comment">// Register the callback for resolving pragma directive</span></div>
<div class="line">  <span class="keywordtype">void</span> SetPragmaCallback(PRAGMACALLBACK_t callback, <span class="keywordtype">void</span> *userParam);</div>
<div class="line"> </div>
<div class="line">  <span class="comment">// Add a pre-processor define for conditional compilation</span></div>
<div class="line">  <span class="keywordtype">void</span> DefineWord(<span class="keyword">const</span> <span class="keywordtype">char</span> *word);</div>
<div class="line"> </div>
<div class="line">  <span class="comment">// Enumerate included script sections</span></div>
<div class="line">  <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> GetSectionCount() <span class="keyword">const</span>;</div>
<div class="line">  <span class="keywordtype">string</span>       GetSectionName(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> idx) <span class="keyword">const</span>;</div>
<div class="line">  </div>
<div class="line">  <span class="comment">// Get metadata declared for classes, interfaces, and enums</span></div>
<div class="line">  <span class="comment">// Each metadata block, i.e. [...], is returned as a separate string</span></div>
<div class="line">  std::vector&lt;std::string&gt; GetMetadataStringForType(<span class="keywordtype">int</span> typeId);</div>
<div class="line"> </div>
<div class="line">  <span class="comment">// Get metadata declared for functions</span></div>
<div class="line">  <span class="comment">// Each metadata block, i.e. [...], is returned as a separate string</span></div>
<div class="line">  std::vector&lt;std::string&gt; GetMetadataStringForFunc(<a class="code hl_class" href="classas_i_script_function.html">asIScriptFunction</a> *func);</div>
<div class="line"> </div>
<div class="line">  <span class="comment">// Get metadata declared for global variables</span></div>
<div class="line">  <span class="comment">// Each metadata block, i.e. [...], is returned as a separate string</span></div>
<div class="line">  std::vector&lt;std::string&gt; GetMetadataStringForVar(<span class="keywordtype">int</span> varIdx);</div>
<div class="line"> </div>
<div class="line">  <span class="comment">// Get metadata declared for a class method</span></div>
<div class="line">  <span class="comment">// Each metadata block, i.e. [...], is returned as a separate string</span></div>
<div class="line">  <span class="comment">// Use the asIScriptFunction for the virtual method for lookup</span></div>
<div class="line">  std::vector&lt;std::string&gt; GetMetadataStringForTypeMethod(<span class="keywordtype">int</span> typeId, <a class="code hl_class" href="classas_i_script_function.html">asIScriptFunction</a> *method);</div>
<div class="line"> </div>
<div class="line">  <span class="comment">// Get metadata declared for a class property</span></div>
<div class="line">  <span class="comment">// Each metadata block, i.e. [...], is returned as a separate string</span></div>
<div class="line">  std::vector&lt;std::string&gt; GetMetadataStringForTypeProperty(<span class="keywordtype">int</span> typeId, <span class="keywordtype">int</span> varIdx);</div>
<div class="line">};</div>
<div class="ttc" id="aclassas_i_script_engine_html"><div class="ttname"><a href="classas_i_script_engine.html">asIScriptEngine</a></div><div class="ttdoc">The engine interface.</div><div class="ttdef"><b>Definition:</b> angelscript.h:1102</div></div>
<div class="ttc" id="aclassas_i_script_function_html"><div class="ttname"><a href="classas_i_script_function.html">asIScriptFunction</a></div><div class="ttdoc">The interface for a script function description.</div><div class="ttdef"><b>Definition:</b> angelscript.h:4000</div></div>
<div class="ttc" id="aclassas_i_script_module_html"><div class="ttname"><a href="classas_i_script_module.html">asIScriptModule</a></div><div class="ttdoc">The interface to the script modules.</div><div class="ttdef"><b>Definition:</b> angelscript.h:2232</div></div>
</div><!-- fragment --><h2><a class="anchor" id="doc_addon_build_1_1"></a>
The include callback signature</h2>
<div class="fragment"><div class="line"><span class="comment">// This callback will be called for each #include directive encountered by the</span></div>
<div class="line"><span class="comment">// builder. The callback should call the AddSectionFromFile or AddSectionFromMemory</span></div>
<div class="line"><span class="comment">// to add the included section to the script. If the include cannot be resolved</span></div>
<div class="line"><span class="comment">// then the function should return a negative value to abort the compilation.</span></div>
<div class="line"><span class="keyword">typedef</span> int (*INCLUDECALLBACK_t)(<span class="keyword">const</span> <span class="keywordtype">char</span> *include, <span class="keyword">const</span> <span class="keywordtype">char</span> *from, CScriptBuilder *builder, <span class="keywordtype">void</span> *userParam);</div>
</div><!-- fragment --><h2><a class="anchor" id="doc_addon_build_1_2"></a>
The pragma callback signature</h2>
<div class="fragment"><div class="line"><span class="comment">// This callback will be called for each #pragma directive encountered by the builder.</span></div>
<div class="line"><span class="comment">// The application can interpret the pragmaText and decide what do to based on that.</span></div>
<div class="line"><span class="comment">// If the callback returns a negative value the builder will report an error and abort the compilation.</span></div>
<div class="line"><span class="keyword">typedef</span> int(*PRAGMACALLBACK_t)(<span class="keyword">const</span> std::string &amp;pragmaText, CScriptBuilder &amp;builder, <span class="keywordtype">void</span> *userParam);</div>
</div><!-- fragment --><h1><a class="anchor" id="doc_addon_build_2"></a>
Include directives</h1>
<p>Example script with include directive:</p>
<pre>
  #include "commonfuncs.as"

  void main()
  {
    // Call a function from the included file
    CommonFunc();
  }
</pre><h1><a class="anchor" id="doc_addon_build_condition"></a>
Conditional programming</h1>
<p>The builder supports conditional programming through the #if/#endif preprocessor directives. The application may define a word with a call to DefineWord(), then the scripts may check for this definition in the code in order to include/exclude parts of the code.</p>
<p>This is especially useful when scripts are shared between different binaries, for example, in a client/server application.</p>
<p>Example script with conditional compilation:</p>
<pre>
  class CObject
  {
    void Process()
    {
  #if SERVER
      // Do some server specific processing
  #endif

  #if CLIENT
      // Do some client specific processing
  #endif 

      // Do some common processing
    }
  }
</pre><h1><a class="anchor" id="doc_addon_build_metadata"></a>
Metadata in scripts</h1>
<p>Metadata can be added before script class, interface, function, and global variable declarations. The metadata is removed from the script by the builder class and stored for post build lookup by the type id, function id, or variable index.</p>
<p>Exactly what the metadata looks like is up to the application. The builder class doesn't impose any rules, except that the metadata should be added between brackets []. After the script has been built the application can obtain the metadata strings and interpret them as it sees fit. Multiple metadata blocks, i.e. [], can be defined for each entity.</p>
<p>Example script with metadata:</p>
<pre>
  [factory func = CreateOgre]
  class COgre
  {
    [editable] 
    vector3 myPosition;

    [editable]
    [range [10, 100]]
    int     myStrength;
  }

  [factory]
  COgre @CreateOgre()
  {
    return @COgre();
  }
</pre><p>Example usage:</p>
<div class="fragment"><div class="line">CScriptBuilder builder;</div>
<div class="line"><span class="keywordtype">int</span> r = builder.StartNewModule(engine, <span class="stringliteral">&quot;my module&quot;</span>);</div>
<div class="line"><span class="keywordflow">if</span>( r &gt;= 0 )</div>
<div class="line">  r = builder.AddSectionFromMemory(script);</div>
<div class="line"><span class="keywordflow">if</span>( r &gt;= 0 )</div>
<div class="line">  r = builder.BuildModule();</div>
<div class="line"><span class="keywordflow">if</span>( r &gt;= 0 )</div>
<div class="line">{</div>
<div class="line">  <span class="comment">// Find global variables that have been marked as editable by user</span></div>
<div class="line">  <a class="code hl_class" href="classas_i_script_module.html">asIScriptModule</a> *mod = engine-&gt;GetModule(<span class="stringliteral">&quot;my module&quot;</span>);</div>
<div class="line">  <span class="keywordtype">int</span> count = mod-&gt;<a class="code hl_function" href="classas_i_script_module.html#a87e29773f7e6f2980d75288faaa74d02">GetGlobalVarCount</a>();</div>
<div class="line">  <span class="keywordflow">for</span>( <span class="keywordtype">int</span> n = 0; n &lt; count; n++ )</div>
<div class="line">  {</div>
<div class="line">    vector&lt;string&gt; metadata = builder.GetMetadataStringForVar(n);</div>
<div class="line">    <span class="keywordflow">for</span>( <span class="keywordtype">int</span> m = 0; m &lt; metadata.size(); m++ )</div>
<div class="line">    {</div>
<div class="line">      <span class="keywordflow">if</span>( metadata[m] == <span class="stringliteral">&quot;editable&quot;</span> )</div>
<div class="line">      {</div>
<div class="line">        <span class="comment">// Show the global variable in a GUI</span></div>
<div class="line">        ...</div>
<div class="line">      }</div>
<div class="line">    }</div>
<div class="line">  }</div>
<div class="line">}</div>
<div class="ttc" id="aclassas_i_script_module_html_a87e29773f7e6f2980d75288faaa74d02"><div class="ttname"><a href="classas_i_script_module.html#a87e29773f7e6f2980d75288faaa74d02">asIScriptModule::GetGlobalVarCount</a></div><div class="ttdeci">virtual asUINT GetGlobalVarCount() const =0</div><div class="ttdoc">Returns the number of global variables in the module.</div></div>
</div><!-- fragment --> </div></div><!-- contents -->
</div><!-- PageDoc -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
  <ul>
    <li class="footer">Generated on Sun May 21 2023 10:12:39 for AngelScript by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.6 </li>
  </ul>
</div>
</body>
</html>
